package com.tiankong.product.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.extension.conditions.query.QueryChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tiankong.product.dto.CategoryDrag;
import com.tiankong.product.entity.Category;
import com.tiankong.product.mapper.CategoryMapper;
import com.tiankong.product.service.CategoryService;
import net.youdi.common.exception.GlobalException;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 * 商品三级分类 服务实现类
 * </p>
 *
 * @author scl
 * @since 2021-03-22
 */
@Service
public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> implements CategoryService {

    @Override
    public void saveCategory(Category category) {
        QueryChainWrapper<Category> wrapper = query().eq("name", category.getName());
        if (category.getParentCid() != null){
            wrapper.eq("parent_cid",category.getParentCid());
        }
        if (category.getCatId() != null){
            wrapper.ne("cat_id",category.getCatId());
        }
        Integer count = wrapper.count();
        if (count >0){
            throw new DuplicateKeyException(String.format("【%s】已存在",category.getName()));
        }
        super.saveOrUpdate(category);
    }

    @Override
    public void batchDelete(Set<Long> ids) {
        Set<Long> hasChildrenIds = findHasChildrenIds(ids);
        if (CollectionUtil.isNotEmpty(hasChildrenIds)){
            List<Category> categories = query().in("cat_id", hasChildrenIds).list();
            StringBuilder msg = new StringBuilder();
            categories.forEach(c-> msg.append("【").append(c.getName()).append("】\n"));
            msg.append("有子节点，不允许删除");
            throw new GlobalException(msg.toString());
        }
        removeByIds(ids);
    }

    @Override
    public void drag(CategoryDrag categoryDrag) {
        Category dragging = categoryDrag.getDragging();
        Category dropNode = categoryDrag.getDragTo();
        String dragType = categoryDrag.getDragType();
        List<Category> updates;
        dragging = getById(dragging.getCatId());
        Integer catLevel = dragging.getCatLevel();
        if ("before".equals(dragType)){
            dragging.setParentCid(dropNode.getParentCid()).setCatLevel(dropNode.getCatLevel());
            updates = query().eq("parent_cid", dragging.getParentCid()).ge("cat_id", dropNode.getCatId())
                    .orderByAsc("sort", "cat_id").list();
            updates.add(0,dragging);
        }else if ("after".equals(dragType)){
            dragging.setParentCid(dropNode.getParentCid()).setCatLevel(dropNode.getCatLevel());
            updates = query().eq("parent_cid", dragging.getParentCid()).ge("cat_id", dropNode.getCatId())
                    .orderByAsc("sort", "cat_id").list();
            updates.add(1,dragging);
        }else{
            dragging.setParentCid(dropNode.getCatId()).setCatLevel(dropNode.getCatLevel()+1);
            updates = query().eq("parent_cid", dragging.getParentCid())
                    .orderByDesc("sort", "cat_id").last("limit 1").list();
            updates.add(dragging);
        }
        //修改排序
        sort(updates);
        if (!catLevel.equals(dragging.getCatLevel())){
            updateChildLevel(dragging,updates);
        }
        updateBatchById(updates);
    }

    @Override
    public Long[] findCatelogPath(Long catelogId) {
        List<Long> paths = new ArrayList<>();
        List<Long> parentPath = findParentPath(catelogId, paths);
        Collections.reverse(parentPath);
        return parentPath.toArray(new Long[parentPath.size()]);
    }
    private List<Long> findParentPath(Long catelogId,List<Long> paths){
        //1、收集当前节点id
        paths.add(catelogId);
        Category byId = this.getById(catelogId);
        if(byId.getParentCid()!=0){
            findParentPath(byId.getParentCid(),paths);
        }
        return paths;

    }
    /**
     * 修改以该节点为父节点的子节点的层级
     * @param root
     * @param updates
     */
    private void updateChildLevel(Category root, List<Category> updates) {

        List<Category> children = query().eq("parent_cid", root.getCatId()).list();
        for (Category category : children) {
            category.setCatLevel(root.getCatLevel()+1);
            updates.add(category);
            updateChildLevel(category,updates);
        }

    }

    private void sort(List<Category> updates) {
        if (CollectionUtil.isNotEmpty(updates)){
            Category first = updates.get(0);
            Integer sort = first.getSort();
            sort = sort == null || 0 ==sort ? 0 : sort-1;
            first.setSort(sort);
            for (Category update : updates) {
                update.setSort(++sort);
            }
        }
    }

    /**
     * 查询有子节点的节点ids
     * @param ids
     * @return
     */
    private Set<Long> findHasChildrenIds(Set<Long> ids) {
        List<Category> children = query().in("parent_cid", ids).list();
        if (CollectionUtil.isNotEmpty(children)){
            return children.stream().map(Category::getParentCid).collect(Collectors.toSet());
        }
        return null;
    }
}
